package com.tcm.user.authentication;

import cn.hutool.core.util.ObjectUtil;
import com.base.core.lang.StringUtils;
import com.base.core.utils.JwtUtils;
import com.base.core.utils.R;
import com.base.genid.generator.UidGenerator;
import com.base.sms.model.entity.VerificationCode;
import com.base.sms.repository.VerificationCodeRepository;
import com.base.sms.service.verification.DefaultVerificationCodeService;
import com.tcm.user.model.entity.LoginAuth;
import com.tcm.user.constants.enums.BusinessCodeEnum;
import com.tcm.user.constants.enums.LoginTypeEnum;
import com.tcm.user.factory.Authenrizer;
import com.tcm.user.persistence.LoginAuthPersisService;
import com.tcm.user.token.AuthenticationToken;
import com.tcm.user.event.LoginEvent;
import org.apache.commons.collections4.map.HashedMap;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;

import java.util.Map;

@Component
public class PhoneCodeAuth implements Authenrizer {

    @Autowired
    private LoginAuthPersisService loginAuthPersisService;

    @Autowired
    private DefaultVerificationCodeService defaultVerificationCodeService;

    @DubboReference(version = "0.0.1-beta", group = "cached-uid", check = false, retries = 3)
    private UidGenerator uidGenerator;

    @Autowired
    private ApplicationEventPublisher applicationEventPublisher;

    private VerificationCodeRepository repository;


    @Override
    public R doGetAuthenticationInfo(AuthenticationToken auth) {
        String mobile = (String) auth.getPrincipal();
        if(StringUtils.isEmpty(mobile)){
            return R.fail(BusinessCodeEnum.SMS_IDENTIFIER_NOT_EMPTY);
        }
        if(StringUtils.isEmpty(auth.getClientType())){
            return R.fail(BusinessCodeEnum.CLIENT_TYPE_PARAMS_NOT_FOUND);
        }
        if(StringUtils.isEmpty(auth.getCredentials())){
            return R.fail(BusinessCodeEnum.SMS_CODE_NOT_FOUND);
        }
        String code = auth.getCredentials().toString();
        //验证短信
        boolean verify = defaultVerificationCodeService.verify(mobile, code, null);

        if(!verify){
            return R.fail(BusinessCodeEnum.SMS_CODE_HAS_ERROR);
        }
        LoginAuth loginAuth = loginAuthPersisService.findByMobile(mobile, auth.getClientType());
        Map<String, Object> claims = new HashedMap<>();
        if(ObjectUtil.isEmpty(loginAuth)){
            //保存登录账号信息
            loginAuth = new LoginAuth();
            loginAuth.setClientType(auth.getClientType());
            loginAuth.setMobile(auth.getPrincipal().toString());
            loginAuthPersisService.save(loginAuth);
            //发布事件
            claims.put("userId", loginAuth.getId());
            LoginEvent loginEvent = new LoginEvent(this, claims);
            applicationEventPublisher.publishEvent(loginEvent);
        }
        JwtUtils jwtUtils = new JwtUtils();
        claims.put("clientType", loginAuth.getClientType());
        claims.put("userId", loginAuth.getId());
        String token = jwtUtils.genToken(loginAuth.getMobile(), claims);
        return R.success(token);
    }

    @Override
    public String supports() {
        return LoginTypeEnum.SMS.type();
    }


}